/*
 * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @Date: 2025-03-21 21:12:06
 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @LastEditTime: 2025-03-22 22:13:55
 * @FilePath: /lesson/Thread_pool/Threadpool.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once
#include <iostream>
#include "Thread.hpp"
#include <string>
#include <vector>
#include <queue>
#include <unistd.h>
#include "Task.hpp"
#include <functional>

using namespace ThreadMoudle;
using namespace std;

static const int gdefault = 5;

void test() // 这里正好 跟回调函数一样：返回值和参数均为空
{
    while (true)
    {
        sleep(1);
        cout << " hello ThreadPool " << endl;
    }
}

template <typename T>
class Threadpool
{

private:
    void LockQueue()
    {
        pthread_mutex_lock(&_mutex);
    }

    void UnlockQueue()
    {
        pthread_mutex_unlock(&_mutex);
    }

    void Wakeup()
    {
        pthread_cond_signal(&_cond);
    }

    void WakeupAll()
    {
        pthread_cond_broadcast(&_cond);
    }

    void Sleep()
    {
        pthread_cond_wait(&_cond, &_mutex);
    }

    bool IsEmpty()
    {
        return _task_queue.empty();
    }

    void HandlerTask(string &name) // 这个函数是 每个线程都要执行的任务！！！
    {
        while (true)
        {
            LockQueue();
            while (IsEmpty() && _isrunning)
            {
                _sleep_thread_num++;
                Sleep();
                _sleep_thread_num--;
            }

            // 只需要判定一种情况了:只要这两个不一起满足，线程池就必须一直运行！
            if (IsEmpty() && _isrunning)
            {
                cout << name << " is quit" << endl;
                UnlockQueue();
                break;
            }

            // 做到此处 就是不为空：有任务
            T t = _task_queue.front(); // ????????????这里的T的含义？？？？？？？？？？？？
            _task_queue.pop();
            UnlockQueue();

            t(); // 处理任务 一定不能在 临界区进行！！！
            cout << name << ":" << t.result() << endl;
        }
    }

public:
    Threadpool(int thread_num = gdefault)
        : _thread_num(thread_num), _isrunning(false), _sleep_thread_num(0)
    {
        pthread_mutex_init(&_mutex, nullptr);
        pthread_cond_init(&_cond, nullptr);
    }

    void Init()
    {
        func_t func = std::bind(&Threadpool::HandlerTask, this, std::placeholders::_1);

        for (int i = 0; i < _thread_num; i++)
        {
            string threadname = "thread- " + to_string(i + 1);
            _threads.emplace_back(threadname, func);
        }
    }

    void Start()
    {
        _isrunning = true;
        for (auto &thread : _threads)
        {
            thread.Start();
        }
    }

    void Stop()
    {
        LockQueue();
        _isrunning = false;
        WakeupAll();
        UnlockQueue();
    }

    void Equeue(const T &in)
    {
        LockQueue();

        if (_isrunning)
        {
            _task_queue.push(in);

            if (_sleep_thread_num > 0)
            {
                Wakeup();
            }
        }

        UnlockQueue();
    }

    ~Threadpool()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_cond);
    }

private:
    int _thread_num;
    vector<Thread> _threads;
    queue<T> _task_queue; // 这里的T的含义:是不是 队列里面每个元素的数据类型？？？？？？？？？
    bool _isrunning;

    int _sleep_thread_num;

    pthread_mutex_t _mutex;
    pthread_cond_t _cond;
};
